#include "StdAfx.h"
#include "ResManager.h"
#include "Elements.h"
#include "Game.h"
#include "DrawWindow.h"
#include "FightingSystem.h"
#include "Statemachine.h"

void CBeauty::Draw(){
	if(!hBm) return;
	SelectObject(W->EmptyDC, hBm); 
	TransparentBlt(W->BackBufferDC, ScrX, Y, Width, Height, W->EmptyDC, 
		XSrc, YSrc, WidthSrc, HeightSrc, 0x00FF00FF);
}


////////////////////////////////////////////////////////////////
//
//
void BackGround::Load(BKG_ID id_i){
	BmId = id_i;
	int StrId =id_i.GetObjInfofileID();
	int ObjId =id_i.GetObjectPicID();

	PWCHAR p = G.RM->LoadObjStr(StrId);
	nLayout = _wtoi(p);
	if(nLayout > nLAYOUT) nLayout = nLAYOUT;
	SO::Move2NextLine(p);
	nBeauty = _wtoi(p);
	SO::Move2NextWord(p);

	pBeauty = new CBeauty[nBeauty];
	for(int i= 0; i< nBeauty; i++){
		int nF = _wtoi(p);
		SO::Move2NextWord(p);
		pBeauty[i].Load(ObjId+0xA0+i, nF);
		pBeauty[i].X =  _wtoi(p);
		SO::Move2NextWord(p);
		int val = _wtoi(p);
		pBeauty[i].Y = W->BBHeight - val - pBeauty[i].HeightSrc;
		SO::Move2NextWord(p);
	}
	G.RM->UnloadObjStr(StrId);

	for(int i= 0; i< nLayout; i++)
	{
		Bm[i].hBm = G.RM->LoadBmp(ObjId + i);//20X00, 20X01...
		GetBitmapSize(Bm[i].hBm, Bm[i].Width, Bm[i].Height);
	}

	Ext[0] = Bm[0].Width - W->BBWidth;
	//the most front one is smaller than windows (Ext0 < 0) ...what's the hell
	//if it equals windows (Ext0 ==0), then other layouts have no need to move...
	if(Ext[0] < 1) return; 
	OffsetX[0] = Ext[0]/2;
	Speed[0] = 1.0f; 

	for(int i= 1; i< nLayout; i++){
		Ext[i]  = Bm[i].Width - W->BBWidth;
		if(Ext[i] < 0) Ext[i] = 0; // Ext  <0 means DO NOT move
		OffsetX[i] = Ext[i] / 2;//initial offset is the middle.
		Speed[i] =  (float)Ext[0] / (float)Ext[i];
	}
}

void BackGround::Unload( ){
	for(int i= 0; i< nLAYOUT; i++){
		if(Bm[i].hBm)
			G.RM->UnloadBmp(Bm[i].hBm);
	}
	BackGround();
}

BackGround::BackGround(){
	for(int i= 0; i< nLAYOUT; i++){
		BmId = 0;
		Bm[i].hBm = 0; Bm[i].Height = Bm[i].Width = 0;
		Speed[i] = 1;
		OffsetX[i] = 0;
		L0Moved = 0;
	}
}

bool BackGround::IsWindowReachEdge(){
	return(OffsetX[0] <= 0 || OffsetX[0] >= Ext[0]);
}

void BackGround::MoveOffset(int id_i, int& Pixel_io){
	int x = OffsetX[id_i] + Pixel_io; 
	if(x <= Ext[id_i] && x >= 0){
		OffsetX[id_i] += Pixel_io; 
		return;
	}

	if(x > Ext[id_i] ){
		Pixel_io = Ext[id_i] - OffsetX[id_i];
		OffsetX[id_i] = Ext[id_i];
		return;
	}

	if( x < 0 ){
		Pixel_io = OffsetX[id_i];
		OffsetX[id_i] = 0;	
	}
	//else, I don't know what's happening
}

//char str[50];

void BackGround::Move(int nPixel_i){
	if(!Bm[0].hBm) return;
	MoveOffset(0,nPixel_i);
	L0Moved += nPixel_i;

	//if(IsEdge(0)) return;
	//sprintf(str, "---\nL0 %d (offset: %d)\n", L0Moved, OffsetX[0]);
	//OutputDebugStringA(str);

	int LnMovePixels;

	for(int i= 1; i< nLAYOUT; i++){
		if(!Bm[i].hBm) continue;
		LnMovePixels = (int)(L0Moved / Speed[i]);
		//if(IsEdge(i)) continue;
		if(LnMovePixels != 0){
			L0Moved =  L0Moved % (int)Speed[i] ; //the pixels left, keep it..
			MoveOffset(i, LnMovePixels);
		}
		//sprintf(str, "L%d %d (offset: %d)\n",i, LnMovePixels, OffsetX[i]);
		//OutputDebugStringA(str);
	}
}

void BackGround::Draw( ){
	for(int i = MaxLayout_Idx; i >= 0; i--){
		if(Bm[i].hBm){
			W->Put2EmptyDC(Bm[i].hBm);
			TransparentBlt(W->BackBufferDC, 0, 0, W->BBWidth, Bm[i].Height, W->EmptyDC, 
				OffsetX[i], 0, W->BBWidth, Bm[i].Height, 0x00FF00FF);
		}
	}//for

	int	ScrXL = OffsetX[0];
	int	ScrXR = OffsetX[0] + W->BBWidth;

	for(int i= 0; i< nBeauty; i++){
		pBeauty[i].IncreaseFrameByTime(G.T->GetTimeSinceStart());//increase frame anyway...

		if((pBeauty[i].X + pBeauty[i].HeightSrc) <= ScrXL)	continue; //out of screen
		if(pBeauty[i].X >= ScrXR)	continue;//out of screen

		pBeauty[i].ScrX = pBeauty[i].X - OffsetX[0];
		pBeauty[i].Draw();
	}
}//function

////////////////////////////////////////////////////////////////
int _wtoh(PWCHAR   p);

////////////////////////////////////////////////////////////////
//
//
void ActionPic::Draw(){
	if(!hBm) return;
	SelectObject(W->EmptyDC, hBm); 
	TransparentBlt(W->BackBufferDC, X - HalfWidth, Y, Width, Height, W->EmptyDC, 
		XSrc, YSrc, WidthSrc, HeightSrc, 0x00FF00FF);
}

Fighter::Fighter(){
	pkc = 0; 
	PerformingUninterrupt = false;
	X =0; 
	FaceRight = true; 
	pActPic = 0;
	CurrentAct = 0x10;
	HP = 100;
}

void Fighter::CalculateRect(int X_i, RECT& HitRect_o, RECT& CoRect_o){
		if(!pActPic) return;
		ActionPic* pAP = pActPic;

		HitRect_o.left= X_i - (pAP->HalfWidth - HITBOUND);
		CoRect_o.left = HitRect_o.left + COBOUNDS;
		HitRect_o.right = X_i + (pAP->HalfWidth - HITBOUND);
		CoRect_o.right = HitRect_o.right - COBOUNDS;
		//char str[50];
		//sprintf(str, "l: %d, r:%d\n", HitRect.left, HitRect.right);
		//if(PlayerId !=0 && HitRect.bottom > 30)OutputDebugStringA(str);
		if(pAP->Head2Top.size() != 0)
			HitRect_o.top =  pAP->GetTopPt() +  pAP->GetHead2Top();
		else
			HitRect_o.top =  pAP->GetTopPt();
		HitRect_o.bottom =  pAP->GetTopPt()  + pAP->Height;
		CoRect_o.bottom = HitRect_o.bottom;
		CoRect_o.top = HitRect_o.top + COBOUNDB;
}

void Fighter::BkPos2ScrPos(){
	ActionPic* pA = pActPic;
	if(!pA) return;
	pA->Y = Y;
	pA->X = X - ScrOffsetX;
}

void Fighter::LoadFighterInfo( ){
	UINT FileId =FtrId.GetObjInfofileID();
	UINT PicId = FtrId.GetObjectPicID();

	WCHAR* p = G.RM->LoadObjStr(FileId);
	while(!SO::IsEndFile(p)){
		ACT_ID ActId = ACT_ID(_wtoh(p));
		SO::Move2NextWord(p);
		//differnt action may use the same Action picture
		//not usual. for jump only, maybe..
		ACT_ID ActPicId = ACT_ID(_wtoh(p)); 
		SO::Move2NextWord(p);
		WORD nFrame = _wtoi(p);
		ActionPic* pA = new ActionPic();
		pA->Load(PicId + ActPicId, nFrame);
		ActId2Pic[ActId] = pA;
		SO::Move2NextWord(p);
		//fix the order of FX HXY HV to every action, so just read them orderly, 
		//no more while for iterator...
		//while(!SO::IsEndFile(p)){
		if(p[0] == L'X' && p[1] ==L'A'){
			p+=3;
			pA->XAcc = _wtoi(p);
			SO::Move2NextWord(p);
		}else{
			pA->XAcc = 0;
		}

		if(p[0] == L'F' && p[1] ==L'Y'){//foot point Y
			p+=3;			
			for(int i =0; i< nFrame; i++){
				int HdPt = _wtoi(p);
				//change it to TopPt:
				HdPt = W->BBHeight - (GROUND + HdPt+ pA->Height);
				pA->TopPt.push_back(HdPt);
				SO::Move2NextWord(p);
			}
		}else{//all FY == 0, so make up it.
			for(int i =0; i< nFrame; i++){
				UINT HdPt = W->BBHeight - (20 + pA->Height);
				pA->TopPt.push_back(HdPt);
			}
		}

		if(p[0] == L'H' && p[1] == L'X' && p[2] == L'Y'){//hit point x,y
			p+=4;
			for(int i =0; i< nFrame; i++){
				POSITION pos;
				pos.x = _wtoi(p);  SO::Move2NextWord(p);
				pos.x/=2;
				pos.y = _wtoi(p);  SO::Move2NextWord(p); 
				pA->HitPt.push_back(pos);
			}
		}

		if(p[0] == L'H' && p[1] ==L' '){ //Height for collision
			p+=2;
			for(int i =0; i< nFrame; i++){
				int ht = _wtoi(p);
				pA->Head2Top.push_back(ht);
				SO::Move2NextWord(p);
			}
		}else{
			for(int i =0; i< nFrame; i++){
				pA->Head2Top.push_back(0);
			}
		}

		if(p[0] == L'H' && p[1] ==L'V'){
			p+=3;
			pA->HitValue = _wtoi(p);
		}else{
			pA->HitValue = 0;
		}

		//SO::Move2NextWord(p); //no more property to read in...
		SO::Move2NextLine(p);
		//}//while
	}//while
	G.RM->UnloadObjStr(FileId);
}

ACT_ID Fighter::GetActIdByInput(){
	KEY_ID Key =  G.INP->GetActionKeys(PlayerId);
	Action* pA;
	if(Key != KEY_NONE){
		pA = CA.MatchKey(pkc, Key);
		if(pA) return pA->ActId;
		return CurrentAct;
	}

	Key = G.INP->GetDirectionKeyByOrder(PlayerId);
	if(Key != KEY_NONE){
		pA = CA.MatchKey(pkc, Key);
		if(pA){return pA->ActId;}
		return CurrentAct;
	}
	return 0x10;
}

bool Fighter::IsInterruptAction(ACT_ID aid_i){
	//0x10 walk, 0x17, 0x27, 0x37  protect
	//0x30 crouch                      
	//0x40 0x50  jump  6 run  9 rush
	//
	switch(aid_i){
		case 0x10: case 0x17: case 0x27: case 0x37: 
		case 0x30: case 0x40: case 0x50:
		case 0x46: case 0x49: case 0x56: case 0x59:
		return true;
	}
	return false;
}

ACT_ID Fighter::SetAction(){
	//interruptable action: (no need to wait for the action to finished, just change it)
	//otherwise, need to wait for the animation to finish.
	double Time = G.T->GetTimeSinceStart();
	ACT_ID a, TempA;

	//still performing the picture
	//UN-interruptable, until it finished.
	if(PerformingUninterrupt){
		pActPic->IncreaseFrameByTime(Time, false);
		if(pActPic->IsAnimFinished()){
			PerformingUninterrupt = false;
			CurrentAct = 0;
		}
		return CurrentAct;
	}

	//old action is going...
	a = GetActIdByInput();
	if(CurrentAct == a){
		pActPic->IncreaseFrameByTime(Time);
		return CurrentAct;
	}
	
	//new action picture should be show up...
	CurrentAct = a;
	if(!IsInterruptAction(a)){
		PerformingUninterrupt = true;
	}

	int ra = 0;
	int act = a - 0x40;
	if(act >=0x0 && act < 0x10){//means move  (right).
		ra = 1;
		if(!FaceRight)	a = 0x50 + act; //but using back image
	}else{
		act = a - 0x50;
		if(act >= 0x0 && act< 0x10){//means move (left)
			ra = 2;
			if(!FaceRight)	a = 0x40 + act; //but using front image
		}
	}

	PA2P p = ActId2Pic.find(a);
	if(p != ActId2Pic.end()){
		pActPic= p->second;
		if(ra >0 ){	RightActDir = ((ra - 1) == 0);}//test if ra == 2
		//for the action moving by itself, not by direction key
		else{RightActDir = FaceRight;}
	}
	//else, no such action picture for this player yet...
	//so don't change it, still showing the old one

	pActPic->ResetFrame();
	pActPic->IncreaseFrameByTime(Time, true);
	return CurrentAct;
}

void Fighter::Draw(){
	if(!pActPic) return;
	if(FaceRight && pActPic->IsFaceLeft()) pActPic->FacingLeft();
	else if(!FaceRight && !pActPic->IsFaceLeft()) pActPic->FacingLeft();
	BkPos2ScrPos();
	pActPic->Draw();
}

void Fighter::Load(PLR_ID PlayerId_i, FTR_ID FId_i){
	PlayerId = PlayerId_i;
	FtrId = FId_i;
	LoadFighterInfo();
	pActPic = ActId2Pic[0x10];
}

void Fighter::Unload( ){
	for(PA2P p = ActId2Pic.begin(); p != ActId2Pic.end(); ++p){
		p->second->Unload();
		delete p->second;
		ActId2Pic.erase(p);
	}
}

////////////////////////////////////////////////////////////////
//
//

CombatSystem::CombatSystem(){
	InitiateUniAction();
	InitiatePlrFtrsBasicAction();
	WasBeenHitting[0] = WasBeenHitting[1] = false;
	FirstHit = _1P;
	Mark[0] = Mark[1] =0;
}

CombatSystem::~CombatSystem(){
	UniAction.clear();

}

void CombatSystem::NewCombat(){
	//initiate player's start position;
	UINT _1of8Scr = W->BBWidth / 8;
	PlrFtr[_1P].X = BK.GetGkOffsetX()+ _1of8Scr;
	PlrFtr[_2P].X = BK.GetGkOffsetX() + (_1of8Scr * 7);
	PlrFtr[_1P].HP = 100;
	PlrFtr[_2P].HP = 100;
	ShowHP.HP[0] = ShowHP.HP[1] = 100;
	ShowHP.Lose[0] = ShowHP.Lose[1] = 0;
}

//different each combat
void CombatSystem::LoadAll(FTR_ID F1Id_i, FTR_ID F2Id_i){
	BK.Unload();
	//use the 1P's home field.
	BK.Load(BKG_ID(F1Id_i));
	PlrFtr[_1P].Load(_1P, F1Id_i);
	PlrFtr[_2P].Load(_2P, F2Id_i);
	PlrFtr[_2P].FaceRight = false;
}


void CombatSystem::Draw(){
	AutoSetPosition();
	BK.Draw();
	ShowHP.Draw( );

	CheckWin();
	PlrFtr[FirstHit].Draw();
	if(FirstHit == _2P)
		PlrFtr[_1P].Draw();
	else 
		PlrFtr[_2P].Draw();
	//ShowRects();
}

bool CombatSystem::IdWasHit(PLR_ID IdWasHit){
	PLR_ID HitId;
	if(IdWasHit == _1P)  HitId= _2P ;else HitId=_1P;

	ActionPic* pHAP = PlrFtr[HitId].pActPic;

	if(pHAP && pHAP ->HitPt.size()){
		POSITION hitpt = pHAP->GetHitPt();
		if(hitpt.x && hitpt.y){
			Fighter& Ftr = PlrFtr[HitId];
			if(Ftr.FaceRight){
				hitpt.x = Ftr.HitRect.left + hitpt.x;
			}else{
				hitpt.x =Ftr.HitRect.right - hitpt.x;
			}
			hitpt.y += Ftr.HitRect.top;
			RECT& r = PlrFtr[IdWasHit].HitRect;
			if(Intersect(hitpt, r))return true;
		}
	}
	return false;
}


//set the X position of Player & Bkgnd;
//collision detection...

bool CombatSystem::IntersectFtr(PLR_ID id_i){
	RECT x;//coflict with each other
	if(IntersectRect(&x, &FCoRect[0], &FCoRect[1]) != 0) return true;
	return false;
}

bool CombatSystem::IntersectWindow(PLR_ID id_i){
	RECT x;//coflict with each other
	if(IntersectRect(&x, &FCoRect[id_i], &OutLeft) != 0) return true;
	if(IntersectRect(&x, &FCoRect[id_i], &OutRight) != 0) return true;
	return false;
}

void CombatSystem::DontChangeX(PLR_ID i){
	PlrFtr[i].Y = PlrFtr[i].pActPic->GetTopPt();
	PlrFtr[i].ScrOffsetX = BK.GetGkOffsetX();
	PlrFtr[i].HitRect = HitRect[i];
	PlrFtr[i].CoRect = FCoRect[i];
}

void CombatSystem::ChangeXY(PLR_ID i){
	PlrFtr[i].ScrOffsetX = BK.GetGkOffsetX();
	PlrFtr[i].X = X[i];
	PlrFtr[i].Y = Y[i];
	PlrFtr[i].HitRect = HitRect[i];
	PlrFtr[i].CoRect = FCoRect[i];
}

//the collision detection function was not satisfiing...
//not perfect. it's a bid deal of fighting game...
void CombatSystem::ChangePostionByCD(){
	bool InTheAir[nP];

	for(int i=0;i<nP;i++){
		ActionPic* pAP2; 
		if(i)pAP2 = PlrFtr[0].pActPic; else pAP2= PlrFtr[1].pActPic;
		ActionPic* pAP = PlrFtr[i].pActPic;
		int fp = pAP->GetFootPt();
		int gnd =  W->BBHeight - GROUND  - (pAP2->Height / 2);
		if(fp < gnd){	InTheAir[i] = true;}
		else{InTheAir[i] = false;}
	}

	//if both in the air or both not, just perform go-or-stop
	if( (!InTheAir[_1P] && !InTheAir[_2P]) ||
		(InTheAir[_1P] && InTheAir[_2P]) )
	{
		for(int i=0;i<nP;i++){
			int id, oid;
			if(i){id = 1; oid =0;}else{id = 0; oid = 1;}
			if(IntersectWindow(i)){
				DontChangeX(i);
				continue;
			}

			//one is backwarding, no Collide will happen.
			if((PlrFtr[id].X > PlrFtr[oid].X && PlrFtr[id].RightActDir) ||
				(PlrFtr[id].X < PlrFtr[oid].X && !PlrFtr[id].RightActDir) )
			{
				ChangeXY(i);
				continue;
			}
			
			if(IntersectFtr(i))
				DontChangeX(i);
			else
				ChangeXY(i);
		}
		return;
	}

	//else ...
	int nia, ia;
	if(InTheAir[_1P] ){
		nia = _2P; ia=_1P; 
	}else{
		nia = _1P; ia = _2P;
	}

	//the one which is not in the air, perform go-or-stop
	if(IntersectWindow(nia) || IntersectFtr(nia)){
		DontChangeX(nia);
	}else{
		ChangeXY(nia);
	}

	//the one in the air, will be moved a little is colliding happed.
	if(!IntersectWindow(ia) && !IntersectFtr(ia)){
		ChangeXY(ia);
		return;
	}

	int l = FCoRect[ia].left;
	int r = FCoRect[ia].right;
	int m = 0;
	int alpha = 0;
	int alphav= 3;

	if(IntersectWindow(ia)  || IntersectFtr(ia))
		do{
			//move forward a little
			alpha +=alphav;
			if(alpha >= PlrFtr[ia].pActPic->Width) //forward doesn't work, move backward
				alphav = -3;
			if(alpha <= - PlrFtr[ia].pActPic->Width){//something unexpected happend...don't what to do...
				DontChangeX(ia);
				return;
			}

			FCoRect[ia].left = l;
			FCoRect[ia].right= r;
			
			if( PlrFtr[ia].RightActDir){
				m = + alpha;
			}else{
				m = - alpha;
			}

			FCoRect[ia].left += m;
			FCoRect[ia].right += m;
			//still colliding do again with a bigger value .

		}while(IntersectWindow(ia) || IntersectFtr(ia));

	X[ia] += m;
	HitRect[ia].left += m;
	HitRect[ia].right += m;
	ChangeXY(ia);
}

//from "this frame" calculate "next frame", this frame was already performed...
void CombatSystem::AutoSetPosition(){
	MakeOutterRects();

	//two temperary Fighter HitRect for testing.
	Fighter& F1P = PlrFtr[_1P];
	Fighter& F2P = PlrFtr[_2P];

	F1P.SetAction();
	F2P.SetAction();

	MakeTestRects();

	ChangePostionByCD();

	Face2Face();
	MoveWindow();

	PLR_ID id;
	if(G.INP->LastPushTime[0] > G.INP->LastPushTime[1]){
		id = _1P; FirstHit= _2P;//then, 1P lose HP.
	}else{
		id = _2P; FirstHit= _1P;
	}

	if(IdWasHit(id)){
		if(WasBeenHitting[id])return;
		WasBeenHitting[id] = true;

		int Lose =  PlrFtr[FirstHit].pActPic->HitValue;

		ShowHP.Lose[id] = Lose;
		PlrFtr[id].HP -= Lose;
		ShowHP.HP[id] =  float(PlrFtr[id].HP)/100.0f;

		//change oid's actionpic to been hit
	}else{
		if(WasBeenHitting[id])WasBeenHitting[id] = false;
	}

	if(IdWasHit(FirstHit)){
		if(WasBeenHitting[FirstHit])return;
		WasBeenHitting[FirstHit] = true;
		
		int Lose =  PlrFtr[id].pActPic->HitValue;

		ShowHP.Lose[FirstHit] = Lose;
		PlrFtr[FirstHit].HP -= Lose;
		ShowHP.HP[FirstHit] = float(PlrFtr[FirstHit].HP)/100.0f;

		//change oid's actionpic to been hit
	}else{
		if(WasBeenHitting[FirstHit])WasBeenHitting[FirstHit] = false;
	}
}

//pre-moved rect for testing
void CombatSystem::MakeTestRects(){
	ActionPic* pAP;
	for(int id= 0; id < nP; id++)
	{
		pAP = PlrFtr[id].pActPic;
		if(!pAP) continue;

		X[id] =PlrFtr[id].X;

		if(pAP->XAcc){
			if(PlrFtr[id].RightActDir){
				X[id] += pAP->XAcc;
			}else{
				X[id] -= pAP->XAcc;
			}
		}
		Y[id] = pAP->GetTopPt();
		PlrFtr[id].CalculateRect(X[id], HitRect[id], FCoRect[id]);
	}

}

//set up two invisible rect just for collision
void CombatSystem::MakeOutterRects(){
	OutLeft.right = BK.GetGkOffsetX();
	OutLeft.top = 0;
	OutLeft.bottom = W->BBHeight;
	OutLeft.left = OutLeft.right - 10000;

	OutRight.left = OutLeft.right + W->BBWidth;
	OutRight.top = 0;
	OutRight.bottom = W->BBHeight;
	OutRight.right = OutRight.left + 10000;
}

void CombatSystem::Face2Face(){
	if(PlrFtr[_1P].CoRect.left > PlrFtr[_2P].CoRect.right) { 
		// 2P is right
		PlrFtr[_1P].FaceRight = false;
		PlrFtr[_2P].FaceRight = true;
	}
	else if(PlrFtr[_2P].CoRect.left  > PlrFtr[_1P].CoRect.right) {
		//2P is at left
		PlrFtr[_1P].FaceRight = true;
		PlrFtr[_2P].FaceRight = false;
	}
}

void CombatSystem::MoveWindow(){
	int MidPt = (PlrFtr[0].X + PlrFtr[1].X) / 2;
	int MidPtShoudMove =  MidPt - (W->BBWidth /2) - BK.GetGkOffsetX();
	if(MidPtShoudMove > 3) MidPtShoudMove = int((float)MidPtShoudMove * 0.1f * 2.0f);
	else if(MidPtShoudMove < -3) MidPtShoudMove = int((float)MidPtShoudMove * 0.1f * 2.0f);
	BK.Move(MidPtShoudMove);
}

void CombatSystem::UnloadAll(){
	BK.Unload();
	PlrFtr[_1P].Unload();
	PlrFtr[_2P].Unload();
}

void CombatSystem::ShowRects(){
	HPEN HitRectPen = CreatePen(PS_SOLID, 2, RGB(255, 0,0));
	HPEN CoRectPen = CreatePen(PS_SOLID, 2, RGB(0,255, 0));
	HDC dc = W->BackBufferDC;
	//SetBkMode(dc, TRANSPARENT);
	int offset = BK.GetGkOffsetX();
	HPEN oldhp;
	char str[50] = {0};

	for( int i = 0; i< 2; i++){
		Fighter& F = PlrFtr[i];

		RECT& hr = F.HitRect;//[i];
		RECT& cr = F.CoRect;//[i];

		int left = hr.left - offset;
		int right = hr.right -offset;
		int coleft = cr.left - offset;
		int coright = cr.right- offset;

		oldhp = (HPEN)SelectObject(dc, HitRectPen);
		MoveToEx(dc, left, hr.top, 0);
		LineTo(dc, left, hr.bottom);
		LineTo(dc,right, hr.bottom);
		LineTo(dc, right, hr.top);
		LineTo(dc, left, hr.top);

		SelectObject(dc, CoRectPen);
		MoveToEx(dc, coleft, cr.bottom, 0);
		LineTo(dc, coleft, cr.top);
		LineTo(dc, coright,cr.top);
		LineTo(dc, coright, cr.bottom);

		if(F.pActPic && F.pActPic->HitPt.size() > 0){
			POSITION p = F.pActPic->GetHitPt();
			if(p.x > 0 && p.y >0){
				if(F.FaceRight)
					TextOutA(dc, F.HitRect.left+ p.x - offset, F.HitRect.top + p.y, "X", 1); 
				else
					TextOutA(dc, F.HitRect.right - p.x - offset, F.HitRect.top + p.y, "X", 1); 
			}
		}

		sprintf(str, "%d,%d       ", hr.right, hr.top);
		TextOutA(dc, right, F.HitRect.top - 15 - (15*i), str, 7);
		sprintf(str, "%d               ", F.X);
		TextOutA(dc, F.X-offset, F.HitRect.top - 15 - (15*i), str,7);
	}
	SelectObject(dc, oldhp);
	DeleteObject(HitRectPen);
	DeleteObject(CoRectPen);
}

bool CombatSystem::CheckWin(){
	bool val = false;
	if(PlrFtr[0].HP <= 0){ Mark[1]++; val = true;}
	if(PlrFtr[1].HP <= 0){ Mark[0]++; val =true;}
	if(Mark[1] == 2){
		Winner = _2P;
		G.SM->IntoRoleSelect();
		return true;
	}
	if(Mark[0] == 2){
		Winner = _1P;
		G.SM->IntoRoleSelect();
		return true;
	}
	if(val){
		G.SM->IntoFighting();
		return true;
	}
	return false;
}

////////////////////////////////////////////////////////////////
//
//
HPShower::HPShower(){
	Width = W->BBWidth / 2 - 30;
	Height = 20;
	X[0] = 15;
	X[1] = 30 + 15 + Width ;
	Y = 10;
	HP[0] = HP[1] = 100;
	Lose[0] = Lose[1] = 0;

	Bar = G.RM->CreateBufferBmp(Width, Height);
}

HPShower::~HPShower(){
	G.RM->UnloadBmp(Bar);
}

void HPShower::Draw(){
	W->Put2EmptyDC(Bar);
	HPEN Red = CreatePen(PS_SOLID, 2, RGB(255, 0 ,0));
	HPEN Green = CreatePen(PS_SOLID, 2, RGB(0,255,0));
	HBRUSH RedB = CreateSolidBrush(RGB(255, 0 ,0));
	HBRUSH GreenB = CreateSolidBrush(RGB( 0,255,0));
	//HPEN old;
	HBRUSH oldB;

	BLENDFUNCTION bf = {AC_SRC_OVER, 0, 0x5f, 0};

	for(int i =0; i< 2; i++){
		oldB = (HBRUSH)SelectObject(W->EmptyDC, GetStockObject(BLACK_BRUSH));
		Rectangle(W->EmptyDC, 0, 0, Width , Height);

		int w = int(HP[i] /100.0 * float(Width));
		//old = (HPEN)SelectObject(W->EmptyDC, Red);
		SelectObject(W->EmptyDC, RedB);
		Rectangle(W->EmptyDC, 0, 1, Width , Height);

		//SelectObject(W->EmptyDC, Green);
		SelectObject(W->EmptyDC, GreenB);
		Rectangle(W->EmptyDC, 0, 0, int(float(Width) * HP[i]), Height);

		//SelectObject(W->EmptyDC, old);
		SelectObject(W->EmptyDC, oldB);
		//BitBlt(W->BackBufferDC, X[i], Y, Width, Height, W->EmptyDC, 0, 0, SRCINVERT);
		AlphaBlend(W->BackBufferDC, X[i], Y, Width, Height, W->EmptyDC, 0, 0, Width, Height, bf);
	}

	DeleteObject(Red);
	DeleteObject(Green);
	DeleteObject(RedB);
	DeleteObject(GreenB);
}

////////////////////////////////////////////////////////////////
//
//
int _wtoh(PWCHAR   p){  
	int  Val = 0; 
	while(true){
		switch(*p){
			case L'0':
				Val   <<=   4; break;
			case L'1': case L'2': case L'3': case L'4': case L'5': case L'6': case L'7': case L'8': case L'9':
				Val   <<=   4;
				Val += *p - L'0'; break;
			case L'a': case L'b': case L'c': case L'd': case L'e': case L'f':
				Val   <<=   4;
				Val += *p  -L'a' +10;  break;
			case L'A': case L'B': case L'C': case L'D': case L'E': case L'F':
				Val   <<=   4;
				Val += *p - L'A' +10;  break;
			default:
				return Val;
		}
		p++;
	}
}
